package com.kapcb.context.core;

import com.kapcb.common.model.UserInfo;
import com.kapcb.context.bean.ThreadContext;
import com.kapcb.context.constant.ApplicationContextConstant;
import lombok.experimental.UtilityClass;

import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * <a>Title: ApplicationThreadContextHolder </a>
 * <a>Author: kapcb <a>
 * <a>Description: ApplicationThreadContextHolder <a>
 *
 * @author kapcb
 * @version 1.0
 * @date 2024/4/20 2:43 PM
 * @since 1.0
 */
@UtilityClass
public class ApplicationThreadContextHolder {

    /**
     * 单例模式
     */
    private static final IThreadContext SINGLETON_THREAD_CONTEXT = new DefaultThreadContextImpl();

    /**
     * 线程上下文中设置用户 id
     *
     * @param userId 用户 id
     */
    public static void putUserId(String userId) {
        SINGLETON_THREAD_CONTEXT.put(ApplicationContextConstant.USER_ID, userId);
    }

    /**
     * 获取用户 id
     *
     * @return 用户 id
     */
    public static Long getUserId() {
        Object userId = SINGLETON_THREAD_CONTEXT.get(ApplicationContextConstant.USER_ID);
        if (Objects.isNull(userId)) {
            UserInfo userInfo = getUserInfo();
            return Objects.isNull(userInfo) ? null : userInfo.getId();
        }
        return (Long) userId;
    }

    /**
     * 线程上下文中设置用户信息
     *
     * @param userInfo 用户信息
     */
    public static void putUserInfo(UserInfo userInfo) {
        SINGLETON_THREAD_CONTEXT.put(ApplicationContextConstant.USER_INFO, userInfo);
        SINGLETON_THREAD_CONTEXT.put(ApplicationContextConstant.USER_ID, userInfo.getId());
    }

    /**
     * 获取用户信息
     *
     * @return 用户信息
     */
    public static UserInfo getUserInfo() {
        Object userInfo = SINGLETON_THREAD_CONTEXT.get(ApplicationContextConstant.USER_INFO);
        if (Objects.isNull(userInfo)) {
            return null;
        }
        return (UserInfo) userInfo;
    }

    /**
     * 根据 key 获取线程上下文中的数据
     *
     * @param key key
     * @param <T> 值
     * @return 值
     */
    public static <T> T get(String key) {
        return SINGLETON_THREAD_CONTEXT.get(key);
    }

    /**
     * 存放数据到线程上下文
     *
     * @param key key
     * @param <T> 值
     * @return 值
     */
    public static <T> T put(String key, T value) {
        return SINGLETON_THREAD_CONTEXT.put(key, value);
    }

    /**
     * 根据 key 移除线程上下文中的数据
     *
     * @param key key
     * @param <T> 值
     * @return 移除的变量值
     */
    public static <T> T remove(String key) {
        return SINGLETON_THREAD_CONTEXT.remove(key);
    }

    /**
     * 清除线程上下文
     */
    public static void clearContext() {
        SINGLETON_THREAD_CONTEXT.clearContext();
    }

    /**
     * 浅拷贝线程上下文数据
     *
     * @return ThreadContext 线程上下文容器
     */
    public static ThreadContext copyContext() {
        return SINGLETON_THREAD_CONTEXT.copyContext();
    }

    /**
     * 深拷贝线程上下文内容
     *
     * @return ThreadContext 线程上下文容器
     */
    public static ThreadContext deepCopyContext() {
        return SINGLETON_THREAD_CONTEXT.deepCopyContext();
    }

    /**
     * 获取线程上下文的所有 k
     *
     * @return 线程上下文的所有 k 集合
     */
    public static Set<String> keySet() {
        return SINGLETON_THREAD_CONTEXT.keySet();
    }

    /**
     * 获取线程上下文的所有 k-v 集合
     *
     * @return 线程上下文的所有 k-v 集合
     */
    public static Set<Map.Entry<String, Object>> entrySet() {
        return SINGLETON_THREAD_CONTEXT.entrySet();
    }

}
